#pragma once

#include <QThread>
#include <QMutex>
#include <QPixmap>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

class VideoCropper : public QThread
{
	Q_OBJECT
public:

	VideoCropper(QMutex *mutex_, QObject *parent=NULL) : QThread(parent)
	{
	//	this->mutex = mutex_;
		roi.width = 0;

		cap_init = cap_end = -1;
	}

	~VideoCropper()
	{
		//delete mutex;
	}

	void run()
	{
		VideoCapture cap;
		if (!cap.open(inputfile))
		{
			emit send_message(tr("Error: Could not open the selected file."));
			return;
		}
		msleep(500);
		
		Mat frame;
		cap.read(frame);

		if (cap_init >= 0)
			cap.set(CV_CAP_PROP_POS_FRAMES, cap_init);
		else
			cap.set(CV_CAP_PROP_POS_FRAMES, 0);

		cv::Size newSize;

		if (roi.width == 0)
			newSize = cv::Size(frame.cols * rescale_factor, frame.rows * rescale_factor);
		else
			newSize = cv::Size(roi.width * rescale_factor, roi.height * rescale_factor);
		
		//video output 
		bool recording = outputfile.size() > 0;

		double fps = (double)cap.get(CV_CAP_PROP_FPS);
		unsigned long frameCount = (unsigned long)cap.get(CV_CAP_PROP_FRAME_COUNT);

		

		if (recording)
		{		
			if (fps <= 0) fps = 29.8;
			if (!out.open(outputfile, CV_FOURCC('D', 'I', 'V', 'X'), fps, newSize))
			{
				emit send_message(tr("Error: Could not open output file."));
			}
		}


		long fc = 0;

		if (cap_init >= 0)
			fc = cap_init;

		long end_cap;
		if (cap_end >= 0)
			end_cap = cap_end;
		else
			end_cap = frameCount;

		while (cap.read(frame) && canRun() && end_cap >= fc)
		{
			fc++;
			if (roi.width > 0)
			{
				frame = frame(roi);
			}

			if (rescale_factor != 1)
			{
				cv::resize(frame, frame, newSize);
			}
			
			if (recording)
			{
				out.write(frame);
			}
			
			emit send_position(frameCount,fc);

			imshow("Output",frame);
			waitKey(1);
		}
		cv::destroyAllWindows();
		cap.release();
		if (recording)
		{
			out.release();
		}

		emit process_finished();
	}

	void setROI(cv::Rect roi)
	{
		this->roi = roi;
	}

	void setRescaleFactor(double scale)
	{
		rescale_factor = scale;
	}

	void setInputFile(std::string value)
	{
		inputfile = value;
	}

	void setOutputFile(std::string value)
	{
		outputfile = value;
	}
	
	void startProcess()
	{
		mutex.lock();
		_canRun = true;
		mutex.unlock();
		start();
	}

	void startPreview()
	{
		startProcess();
		outputfile = "";
	}

	void stopProcess()
	{
		mutex.lock();
		_canRun = false;
		mutex.unlock();
	}

	void setInitEnd(long init, long end)
	{
		cap_init = init;
		cap_end = end;
	}


protected:

	bool canRun()
	{
		mutex.lock();
		bool res = _canRun;
		mutex.unlock();
		return res;
	}

	VideoCapture cap;
	VideoWriter out;
	std::string inputfile;
	std::string outputfile;
	cv::Rect roi;
	double rescale_factor;

	long cap_init, cap_end;

	QMutex mutex;
	bool _canRun;

signals:
	void show_image(QPixmap);
	void send_message(QString);
	void send_position(long, long);
	void process_finished(void);
};


